home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CU Amiga Super CD-ROM 19
/
CU Amiga Magazine's Super CD-ROM 19 (1998)(EMAP Images)(GB)[!][issue 1998-02].iso
/
CUCD
/
Demos
/
Eurochart31
/
Articles
/
CoderCoursePart1
< prev
next >
Wrap
Text File
|
1997-10-06
|
14KB
|
531 lines
»SML:»CL9:--------------------------------------
»SML:»CL8: »BIG:Coder's Course
»SML: »BIG:Part 1
»SML:»CL9:--------------------------------------
»CL4: By Cytron/Depth
»CL0:OK, all you dear »CL1:"I've seen a lot of
demos and want to code"»-sceners, I'm
offering you a nice little
assemblercourse for free. I guess that
there are loads of those already, but
as I learned coding pretty easy
myself, I thought that my approach
might be a good one. The approach is
simply »CL1:getting into all the good sides
of Amiga right away» - let the
assembler do the understanding for you
in the beginning, and just code
something. And don't worry about
copper, blitter, c2p, etc.. Just learn
to control simple methods right away,
and make a few small things that
demomnstrate that 'I can do it', and
makes you want to go further into it!
ANYWAY, that was my appoach 6 months
ago, and I've coded 3 demos already.
Besides, I'm working on a 4k. So, this
is what YOU can do in 3 months from
now! Anyway, let's get started with...
»CL8:The simple mathematical stuff,
that ALL sceners should know!:
»SML:»CL1:Hexadeciaml representation:»CL0: When
writing $FE it simply means 254,
namely 16*$F+$E = 16*15+14=254.
»CL1:Signed/Unsigned:» When viewing at a
number as signed, The most significant
bit determines the sign.. If set, the
number is negative and the number is
all the other bits inverted plus 1.
This is easier to see than to explain:
eg., signed words:
»CL1: $FE65 = -$019B = - 411
$3444 = $3444 = 13380
$FF56 = -$00AA = - 170
$8645 = -$79BB = - 31163
$5634 = $5634 = 22068
$0064 = $0064 = 100
$C000 = -$4000 = - 16384
$FFFF = -$0001 = - 1
»
»CL8: »BIG:The registers:
»SML:»CL9:--------------------------------------
»CL0:The MC68xxx contains »CL1:16 registers, 8
data- and 8 address-registers (d0-d7
and a0-a7)». The difference between
the two types of registers will be
explained later in this chapter.
From now on, aX will mean an
addressregister and dX will mean a
dataregister. The registers are
32-bit, simply meaning that a register
contains 32 bits of data, that is up
to $FFFFFFFF. When using commands
that refer to registers, one has to
specify which part of the register is
being used. Let's look at the three
ways of 'looking at' a register,
»CL1:eg. if d0 = $FE673C41, then
d0 as longword is $FE673C41
d0 as word is $3C41
d0 as byte is $41
»It's as simple as that!
When using this principle in an
assembler, one simply writes »CL1:d0.l»,
»CL1:d0.w», or »CL1:d0.b» (Omitting this will
usually make the assembler
»CL8:The basic instructions for this part:
»BIG: move, add, sub, muls/mulu
»SML:»CL9:--------------------------------------------------------------------------------
»CL0:All of these instructions have the following usage:
»CL1: command a,b »CL0: means do the command from a to b.
eg.»CL4: move.w d1,d2 »CL5: ; move the contents in d1 as word to d2 as word.
»CL4: add.b d7,d0 » ; add d7.b to d0.b. Please note that only the byte in
; d0 is affected, no matter what the result of the add is.
»CL4: sub.w d0,a0 » ; subtract d0 from a0. (Remeber to check the note
; about addressregisters later)
»CL4: mulu.w d0,d0 » ; multiply d0.w Unsigned with itself and put it in d0.l
; (this one is special, since we're multiplying)
»CL4: muls.w d3,d2 » ; multiply d3.w with d2.w both viewed upon as SIGNED,
; and store the result in d2.l signed.
»CL0:interpretate it as d0.w, but »CL1:PLEASE»
get used to »CL1:ALWAYS» writing the
extensions. The code get's easier to
grasp that way!)
»CL8: »BIG:Regarding address/dataregisters:»SML:
»CL9: -----------------------------------------------
»CL0:Addressregisters are mainly used to The simplest addressing modes:
point onto some memory, not to perform When wanting to read/write from/to
arithmetic instruction upon. memory, the smartest approach is to
Therefore, only add, sub and move store the source/destination-address
works with addressregisters.. And it's in an address-register, and then
a little more complex than that. So, writing to the memory from there. To
for now, just leave the demonstrate this, I'll make a little
adressregisters when doing example that will also show you the
arithmetical instructions. IMMEDIATE priciple:
»CL4:Start: move.l #30,d0 »CL5:; Moves 30 into d0. d0 = $0000001E
»CL4: lea Space,a0 »; Let a0 point at Space
»CL4: move.b d0,(a0) »; move d0 as byte into Space. Space = $1E000000
»CL4: move.w d0,(a0) »; move d0 as word into Space. Space = $001E0000
»CL4: move.l d0,(a0) »; hehe... Space = $0000001E
»CL4: rts »; Return to assembler
»CL4:Space: dc.l 0 »; When this is assembled, Space = $00000000
»CL0:As you see, using »CL1:(aX)» means »CL1:AT» the
address stored in aX.
You might also mark that I've used an
immidiate move. I've moved the number
30 into d0. »CL1:(You might wonder why I've
moved as longword. The reason is that
I clear the entire register, so that I
know for sure that d0.l = $0000001E)»
»CL8:»BIG:Let's start up our assembler:
»CL9:»SML:--------------------------------------
»CL0:It's time for you to experiment a
little bit yourselves. Being in an
assembler and watching what happens is
the fastest way to learn anything. I
will strongly recommend you to use
»CL1:AsmOne 1.29», as this assembler is
very straightforward and has a
brilliant singlestepdebug feature
(What a great word!). These examples
apply for AsmOne 1.29. They might work
in other assembler as well, but I
wouldn't know!
Type the little program, I've made, in
your assembler (Escape of course
toggles between editing the source and
controlling the whole thing). Now try
this:
»CL2:a»
The thing should now assemble your
code in hopefully report No Errors.
When this is done, try typing
»CL2:h Space»
Now a lot of numbers should pop up at your screen. Like this:
»CL7:0822450C 00 00 00 00 12 34 56 78 01 01 00 00 00 08 00 00 ".....4Vx........"
0822451C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "................"
0822452C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "................"
»CL0:^^^^^^^^ ^^ ^^^^^^^^^^^^^^^^
Address Data as Hex. Each line contains 16 bytes of data. Data as AscII
(Escape let's you out again)
What we've just seen is the data at the label Space.
If we change the line
»CL4:Space: dc.l 0
»to
»CL4:Space: dc.l $CAFEBABE
», our memory will (after assembling again) look like this:
»CL7:08224514 »CL6:CA FE BA BE» 12 34 56 78 01 01 00 00 00 08 00 00 "Êþº¾.4Vx........"
08224524 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "................"
08224534 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "................"
»
»CL0:As you can see, The memory has now been changed.
Now let's try writing:
»CL2:h Start
»CL7:08224500 20 3C 00 00 00 1E 41 F9 08 22 45 14 10 80 30 80 " <....Aù."E..`0`"
08224510 20 80 4E 75 CA FE BA BE 12 34 56 78 01 01 00 00 " `NuÊþº¾.4Vx...."
08224520 00 08 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "................"
»CL0:Now, we're at another location in memory close to the other one (you can see
CAFEBABE someplace!)
While we're in this HEX-viewer, try pressing »CL1:RAMIGA+d» (Disassemble).
Now we get:
»CL7:08224500 203C0000001E MOVE.L #$0000001E,D0
08224506 41F908224514 LEA $08224514,A0
0822450C 1080 MOVE.B D0,(A0)
0822450E 3080 MOVE.W D0,(A0)
08224510 2080 MOVE.L D0,(A0)
08224512 4E75 RTS
08224514 CAFE DC $CAFE
08224516 BABE DC $BABE»
^^^^^^^^ ^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
Address Instruction as Code Instruction
In other words, this is what the computer gets out of our little
program. You should note that the »CL7:LEA $08224514,A0»
moves exactly the address we wanted (The label Space) into a0.
Now let the real fun begin.. (Escape).
Let's singlestepdebug our little
program! Type:
»CL2:ad»
, which means assemble/debug.
»CL1:Whoaa...» You're in the 'editor', and a
black line is on the first line in the
program. The contents of all registers
are to the right.
Now try pressing arrow down. And see,
that d0 contains 0000001E.
Do this until you've reached the
»CL4:move.w d0,(a0)»
, then press escape. Now examine
what's on »CL1:Space» (h Space for the slow
ones of you!!). It should definately
not be CAFEBABE anymore! Great!
Finally, try just pressing
»CL2:a
j»
And the entire program runs to the end
»CL1:(until rts is encountered)». Now again
examine »CL1:Space».
This isn't very hard, I know!
So know let's try generating a little
table.
For this we need to learn a little bit
about »CL1:branching». Let's introduce...
»CL8: »BIG:The bxx command(s):
»CL9:»SML: -----------------------------------------
»CL0:The »CL1:bxx» is not ONE command, it's loads
of commands. Let's make little
example:
»CL4:Start: move.b #$80,d1
move.b #$80,d0
sub.b d0,d1
beq Stop
move.l #$DEADBEEF,d0
Stop: rts
»
Before you run this program, let me
ask you? Does d0 contain $DEADBEEF
after this program has been run? :-)
OK... As you might hvae guessed, the
»CL1:beq» command means »CL1:branch to the label
Stop if the result was zero.»
What actually happens is that the
computer has got a »CL1:FLAGREGISTER»,
containing information about the
result of the last arithmetic
operation.
The flags are:
»CL1: Z (Zero)
N (Negative)
C (Carry)
V (oVerflow)»
Explaining the use of this would bore
you to death, I think. The only
intersting things to say are perhaps
that
- the carry flag is set if an addition
or multiplication hs a result bigger
than can be in the register.
- the V-flag is used on signed values.
What is much more important is that the flags can be seen »CL1:BENEATH» the
registers when »CL1:singlestepping». Try singlestepping the little program and
watch the flags, as you move numbers into registers »CL1:(Note: $80.b = -$80),»
and as you subtract. The many types of branching depend on the flags as this:
»CL4:beq »CL5:(EQual): » Z-flag set.
bne »CL5:(Not Equal): » Z-flag not set.
bmi »CL5:(MInus): » N-flag set.
bpl »CL5:(PLus): » N-flag not set.
bcs »CL5:(Carry Set): » C-flag set.
bcc »CL5:(Carry Clear): » C-flag not set.
bvs »CL5:(oVerflow Set): » V-flag set.
bvc »CL5:(oVerflow Clear): » V-flag not set.
blt »CL5:(Less Than): » V-flag the same as N-flag AND Z-flag not set.
ble »CL5:(Less or Equal): » V-flag the same as N-flag.
bge »CL5:(Greater Than): » V-flag not the same as N-flag AND Z-flag not set.
bgt »CL5:(Greater or Equal):» V-flag not the same as N-flag
blo »CL5:(LOwer): » C-flag set.
bls »CL5:(Lower or Same): » C-flag set OR Z-flag set
bhs »CL5:(Higher or Same): » C-flag not set.
bhi »CL5:(HIgher): » C-flag not set OR Z-flag set
»CL0:As you see, this can get rather
complicated. Some of these commands
are supposed to be used after the
»CL1:cmp»-command (compare). But for now,
let's just stick to »CL1:beq» and »CL1:bne». These
two can take us a long way! »CL1:They can
make us do loops!»
Before we begin, let me introduce you
to a quite handy adressing mode:
»CL4: move.X something,(aX)+
move.X something,-(aX)
»This is extremely neat, »CL1:as it will add/subtract either 1,2, or 4 to/from
aX every time some data has been written to it.»
eg:»CL4: add.w d0,(a0)+»CL5: ; add d0.w to the location of a0 and then add 2 to a0
»CL4: sub.b d1,-(a1)» ; subtract 1 from a1 and then
; subtract d1.b from the location of a1.
»CL4: move.l #0,(a2)+ »; move $00000000 to the location of a2 and then
; add 4 to a2.
»CL0:Our first decent program will make a
square table (word-size) of the
numbers 0-255. This isn't hardcoded,
as I might confuse you a bit by smart
optimizing!
»BIG:»CL8:Let's do it!:
»SML:»CL9:-------------------------------------------------------------------------------
»CL4:Squares: move.w #0,d0 »CL5: ; The number, we're at
»CL4: lea SquareTable,a0 »; Find our table.
»CL4:Loop: move.w d0,d1
mulu.w d1,d1 » ; The square. Unsigned!
»CL4: move.w d1,(a0)+ » ; Move the square into the table,
; then add 2 to a0
»CL4: add.w #1,d0 » ; The next number
»CL4: cmp.w #256,d0 » ; Are we finished?
»CL4: bne Loop » ; If not, then loop.
»CL4: rts
SquareTable: dcb.w 256,0 » ; Declare 256 words as 0
»CL0:You should try to test if the program
has done what it should by simply
checking if the SquareTable consists
the 256 squares after jumping. (a, j,
h SquareTable).
And by all means, try
singlestepdebugging it and watch what
happens in the registers!
This concludes the first lesson of
coding. I hope that some of you are
inspired to make something out of
coding now. Or at least to stay tuned
here. Coding isn't as hard as it
seems. Stay tuned for the next lesson,
where we will go further into
adressing and perhaps take a brief
look at some optimizingmethods plus
some more assembler-specific tricks.